package chagine.mdt.service.sqlservice.yy;

import chagine.core.ErrorCode;
import chagine.core.util.Assert;
import chagine.mdt.feign.UserClient;
import chagine.mdt.mapper.yy.YyDxDxtabMapper;
import chagine.mdt.po.yy.YyDxDxtab;
import chagine.mdt.po.yy.YyDxcodeDx;
import chagine.mdt.vo.yy.AdmissionDiagnosisV2Vo;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import java.util.stream.Collectors;

/**
 * <p>
 * 诊断表 服务实现类
 * </p>
 *
 * @author lsf
 * @since 2023-04-13
 */
@Service
public class YyDxDxtabService extends ServiceImpl<YyDxDxtabMapper, YyDxDxtab> {
    private static final AdmissionDiagnosisV2Vo EMPTY = new AdmissionDiagnosisV2Vo();
    @Resource
    private YyDxcodeDxService yyDxcodeDxService;
    @Resource
    private YySysUserService yySysUserService;
    @Resource
    private YySysPatientService yySysPatientService;
    @Resource
    private UserClient userClient;

//    public List<AdmissionDiagnosisV2Vo> listYyDxDxtab(Long puerperaId, Integer deagnosticCategoryType) {
//        String inHospitalId = puerperaService.getInHospitalId(puerperaId);
//        Assert.error(inHospitalId == null, ErrorCode.BUSINESS_EXCEPTION, "住院号不存在");
//        return baseMapper.listYyDxDxtab(deagnosticCategoryType, inHospitalId);
//    }

    private List<AdmissionDiagnosisV2Vo> privateListYyDxDxtab(String inHospitalId, Integer deagnosticCategoryType) {
        List<AdmissionDiagnosisV2Vo> list = baseMapper.listYyDxDxtab(deagnosticCategoryType, inHospitalId);
        return list.stream().filter(t -> StringUtils.isNotEmpty(t.getIcd10())).collect(Collectors.toList());
    }

//    public List<AdmissionDiagnosisV2Vo> listYyDxDxtab(String inHospitalId, Integer type) {
//        return listYyDxDxtab(inHospitalId, type, false);
//    }

    /**
     * 诊断列表
     * @param inHospitalId 住院号
     * @param type 诊断类型
     */
    public List<AdmissionDiagnosisV2Vo> listYyDxDxtab(String inHospitalId, Integer type) {

        Assert.error(inHospitalId == null, ErrorCode.BUSINESS_EXCEPTION, "住院号不存在");

        // 如院诊断
        if (type == 2) {
            return listYyDxDxtab(inHospitalId);
        }

        List<AdmissionDiagnosisV2Vo> admissionDiagnosisV2Vos = privateListYyDxDxtab(inHospitalId, type);
        if (!admissionDiagnosisV2Vos.isEmpty()) {
            return admissionDiagnosisV2Vos;
        }

        return admissionDiagnosisV2Vos;
    }

    /**
     * 合并处理后的诊断
     * @param inHospitalId
     * @return
     */
    private List<AdmissionDiagnosisV2Vo> listYyDxDxtab(String inHospitalId) {

        // 诊断类别 0初步 55补充 1修正 2入院 3出院 20术前 21术后 300 病案首页
        List<AdmissionDiagnosisV2Vo> admissionDiagnosis55List = privateListYyDxDxtab(inHospitalId, 55);
        List<AdmissionDiagnosisV2Vo> admissionDiagnosis2List = privateListYyDxDxtab(inHospitalId, 2);
        List<AdmissionDiagnosisV2Vo> admissionDiagnosis1List = privateListYyDxDxtab(inHospitalId, 1);
        if (admissionDiagnosis1List.isEmpty()) {
            admissionDiagnosis1List = privateListYyDxDxtab(inHospitalId, 0);
        }

        // 合并诊断
        List<AdmissionDiagnosisV2Vo> admissionDiagnosisList = admissionDiagnosis55List;
        admissionDiagnosisList.addAll(admissionDiagnosis2List);
        admissionDiagnosisList.addAll(admissionDiagnosis1List);

        // 去重
        admissionDiagnosisList = admissionDiagnosisList.stream().collect(
                Collectors.collectingAndThen(Collectors.toCollection(()-> new TreeSet<>(Comparator.comparing(AdmissionDiagnosisV2Vo::getIcd10))),
                        ArrayList::new)
        );

        if (admissionDiagnosisList.isEmpty()) {
            return admissionDiagnosisList;
        }

        for (int i = 0; i < admissionDiagnosisList.size(); i++) {
            admissionDiagnosisList.get(i).setIndexNo(i);
        }

        return admissionDiagnosisList;
    }

    private List<YyDxDxtab> toDeleteData(List<String> deleteList, String doctorId) {
        LocalDateTime now = LocalDateTime.now();
//        String nowStr = LocalDateTimeUtil.formatNormal(now);
        return deleteList.stream().map(id -> {
            YyDxDxtab t = new YyDxDxtab();
            t.setId(id);
            t.setDxcode("");
            t.setIcd("");
            t.setDxname("");
            t.setDoctorid(doctorId);
            t.setUpdatetime(now);

            return t;
        }).collect(Collectors.toList());
    }

    private List<YyDxDxtab> toAddData(List<AdmissionDiagnosisV2Vo> list, int type, String patientid, String doctorId) {
        LocalDateTime now = LocalDateTime.now();
        String nowStr = LocalDateTimeUtil.formatNormal(now);
        int id = nextId();
        int size = list.size();
        List<YyDxDxtab> newList = new ArrayList<>(size);
        for (int i = 0; i < size; i++) {
            AdmissionDiagnosisV2Vo vo = list.get(i);

            String icd = vo.getIcd10();
            YyDxcodeDx dxcode = yyDxcodeDxService.getByIcd10(icd);
            YyDxDxtab t = new YyDxDxtab();
            t.setId(String.valueOf(id + i));
            t.setPatientid(patientid);
            t.setDxindex(vo.getIndexNo().toString());
            t.setDxcode(icd);
            t.setIcd(icd);
            t.setDxname(dxcode.getDxname());
            t.setDxnamesup(vo.getSupplementaryDiagnosis());
            t.setDxdiagnosis(vo.getDxdiagnosis());
            t.setDxcategory(String.valueOf(type));
            t.setDoctorid(doctorId);
            t.setUpdatetime(now);
            t.setWritingtime(nowStr);
            t.setDxtime(nowStr);

            newList.add(t);
        }
        return newList;
    }

//    /**
//     * 诊断表修改
//     * @param vo 修改对象
//     */
//    public void update(YyDxDxtabVo vo) {
//        String id = vo.getId();
//        update(
//                Wrappers.<YyDxDxtab>lambdaUpdate()
//                        .set(YyDxDxtab::getPatientid, vo.getPatientid())
//                        .set(YyDxDxtab::getDxindex, vo.getDxindex())
//                        .set(YyDxDxtab::getDxcode, vo.getDxcode())
//                        .set(YyDxDxtab::getIcd, vo.getIcd())
//                        .set(YyDxDxtab::getDxname, vo.getDxname())
//                        .set(YyDxDxtab::getDxnamesup, vo.getDxnamesup())
//                        .set(YyDxDxtab::getDxdiagnosis, vo.getDxdiagnosis())
//                        .set(YyDxDxtab::getResultid, vo.getResultid())
//                        .set(YyDxDxtab::getDxcategory, vo.getDxcategory())
//                        .set(YyDxDxtab::getDoctorid, vo.getDoctorid())
//                        .set(YyDxDxtab::getWritingtime, vo.getWritingtime())
//                        .set(YyDxDxtab::getDxtime, vo.getDxtime())
//                        .set(YyDxDxtab::getReportcardType, vo.getReportcardType())
//                        .set(YyDxDxtab::getReportedcardType, vo.getReportedcardType())
//                        .set(YyDxDxtab::getUnreportedReason, vo.getUnreportedReason())
//                        .set(YyDxDxtab::getFatherid, vo.getFatherid())
//                        .set(YyDxDxtab::getOperationid, vo.getOperationid())
//                        .set(YyDxDxtab::getMainoperationid, vo.getMainoperationid())
//                        .set(YyDxDxtab::getDxstate, vo.getDxstate())
//                        .set(YyDxDxtab::getDxtype, vo.getDxtype())
//                        .set(YyDxDxtab::getSyndromesicd, vo.getSyndromesicd())
//                        .set(YyDxDxtab::getSyndromesname, vo.getSyndromesname())
//                        .set(YyDxDxtab::getMaindx, vo.getMaindx())
//                        .set(YyDxDxtab::getDxposition, vo.getDxposition())
//                        .set(YyDxDxtab::getAnatomyname, vo.getAnatomyname())
//                        .set(YyDxDxtab::getAdmissionIs, vo.getAdmissionIs())
//                        .set(YyDxDxtab::getSuperiorDoctors, vo.getSuperiorDoctors())
//                        .set(YyDxDxtab::getDrgs, vo.getDrgs())
//
//                        .set(YyDxDxtab::getUpdatetime, LocalDateTime.now())
//                        .eq(YyDxDxtab::getId, id)
//        );
//    }

    private Integer nextId() {
        Integer max = max();
        if (max == null) {
            max = 0;
        }

        max++;

        return max;
    }

    private Integer max() {
        String idStr = getObj(
                Wrappers.<YyDxDxtab>query()
                        .select("MAX(ID)"),
                t -> (String) t
        );
        if (idStr == null) {
            return null;
        }
        return Integer.parseInt(idStr);
    }

}
